package com.ht.web360.PojServer.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ht.web360.PojServer.dao.PojInfo;
import com.ht.web360.PojServer.mapper.PojInfoMapper;
import com.ht.web360.base.dto.PojInfo.dto.PojInfoDto;
import com.ht.web360.base.dto.RPage;
import com.ht.web360.base.feignApi.Oss;
import com.ht.web360.base.utils.RedisIdWorker;
import com.ht.web360.base.utils.ThreadLocalUtil;
import com.ht.web360.base.utils.exceptions.MessageException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
public class PojInfoService {
    @Lazy
    @Autowired
    private PojInfoService _this;

    private final PojInfoMapper pojInfoMapper;
    private final RedisIdWorker redisIdWorker;
    private final Oss oss;
    private final ObjRefService objRefService;

    public PojInfoService(PojInfoMapper pojInfoMapper, RedisIdWorker redisIdWorker, Oss oss, ObjRefService ObjRefService) {
        this.pojInfoMapper = pojInfoMapper;
        this.oss = oss;
        this.objRefService = ObjRefService;
        this.redisIdWorker = redisIdWorker;
    }

    @Cacheable(cacheNames = "PojInfoDto", key = "#p0")
    public PojInfoDto getById(String id) {
        if (StrUtil.isBlankIfStr(id) || !NumberUtil.isLong(id)) {
            throw new IllegalArgumentException();
        }
        PojInfo pojInfo = pojInfoMapper.selectById(id);
        if (pojInfo == null) {
            throw new MessageException("项目不存在");
        }
        return pojInfo.toDto();
    }

    @Transactional
    @CacheEvict(cacheNames = "PojInfoDto", key = "#p0.id")
    public void updateById(PojInfoDto pojInfoDto) {
        if (StrUtil.isBlankIfStr(pojInfoDto.getId())) {
            throw new IllegalArgumentException();
        }
        pojInfoDto.setCoverLink(null);
        pojInfoDto.setCreateTime(null);
        pojInfoDto.setUpdateTime(null);
        pojInfoMapper.updateById(PojInfo.getInstance(pojInfoDto));
    }

    @Transactional
    public void savePojInfo(PojInfoDto pojInfoDto) {
        _this.savePojInfo(PojInfo.getInstance(pojInfoDto));
    }

    @Transactional
    public void savePojInfo(PojInfo pojInfo) {
        if (pojInfo == null ||
                StrUtil.isBlankIfStr(pojInfo.getName()) ||
                pojInfo.getPojType() == null
        ) {
            throw new IllegalArgumentException("参数错误");
        }

        pojInfo.setId(redisIdWorker.nextId());
        pojInfo.setCreatorId(ThreadLocalUtil.getUserId());
        pojInfo.setCreateTime(null);
        pojInfo.setUpdateTime(null);
        pojInfoMapper.insert(pojInfo);
    }

    @Transactional
    @CacheEvict(cacheNames = "PojInfoDto", key = "#p0")
    public void uploadCover(String id, MultipartFile file) {
        String md5 = oss.upload(file);
        if (StrUtil.isBlankIfStr(md5)) {
            throw new MessageException("上传失败，请稍后重试");
        }
        try {
            PojInfoDto pojInfo = _this.getById(id);
            PojInfo info = PojInfo.getInstance(pojInfo);
            if (StrUtil.isNotBlank(info.getCoverLink()) && !info.getCoverLink().equals(md5)) {
                oss.delete(info.getCoverLink());
            }
            info.setCoverLink(md5);
            pojInfoMapper.updateById(info);
        } catch (Exception e) {
            oss.delete(md5);
            throw e;
        }
    }

    @Transactional
    @CacheEvict(cacheNames = "PojInfoDto", key = "#p0")
    public void deleteById(String id) {
        if (StrUtil.isBlankIfStr(id) || !NumberUtil.isLong(id)) {
            throw new IllegalArgumentException();
        }
        int state = pojInfoMapper.deleteById(id);
        if (state == 0) {
            throw new MessageException("删除失败");
        }
        objRefService.deleteByPojId(Long.parseLong(id));
    }

    public RPage<PojInfoDto> pageInfo(long current, long size) {
        IPage<PojInfo> iPage = new Page<>(current, size);
        var query = new LambdaQueryChainWrapper<>(PojInfo.class);
        pojInfoMapper.selectPage(iPage, query);
        return RPage.getInstance(iPage, PojInfo::toDto);
    }
}
